home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
fdimg
/
—‹Œêsrc.lzh
/
work.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-18
|
29KB
|
1,195 lines
#include "3DDEF.H"
#include "GLOBAL.H"
#include "FORWARD.H"
#include "XCODE.H"
extern UWORD CRX,CRY;
/* エディタのコア */
void
work()
{
if (DUM_FLAG) {
fep_hmode_set((UBYTE)'M');
disp_hmode(); /* 一番下の行に変換モード表示を行う */
}
work_line_analyze(); /* 行の解析 */
CX = CX0 = CY = CPX = 0; /* 現在のカーソル位置(相対) */
work_cursor_cpx();
while(1) {
commander();
}
}
UBYTE l[VERY_LONG_LINE*8], s[VERY_LONG_LINE*8], w[VERY_LONG_LINE*8]; /* 十分なエリア */
/* 現在のカーソル位置に文字列を挿入する:エコーする */
/* あまり凶悪に長いのはだめよ */
void
work_insert_str(STR s)
{
int len;
register int i;
len = strlen(s);
line_cl_strncpy(l,i = ANALYZE[CPX].BPOS); /* ok */
l[i] = EOS;
strcat(l,s);
line_cl_strcat(l,i); /* ok */
work_cl_replace_plus(i+len);
}
/* 現在行の指定区間を削除する */
/* フラグにより、バッファに入れる */
void
work_delete_cl_between(int b1,int b2,int flag)
{
UNIT *wp,*wp0;
line_seigyou();
line_get_body(l,CL);
work_delete_between(CL,b1,b2,flag);
line_get_body(l,CL);
if (string_disp_len(l)) { /* まだ実体が残っている */
if (CL->ATO == TAIL) {
register int y;
line_store_and_echo(CL,l);
/* CL の b1 に行く */
for(y = CY+1;y <= (CWY1-CWY0);y++) {
disp_half_line_rel(0,y,(STR) "");
}
/* work_cl_replace_plus(b1);*/
return;
}
/* line_cat_body(l,CL->ATO);*/
/* line_delete1_echo_after_bag(CL->ATO);*/
/* line_delete1(CL->ATO);*/
/* line_deleten_SCREEN(CL,(CL->ATO)->ATO);*/
work_cl_replace_plus(b1);
} else {
if ((wp0 = CL->ATO) != TAIL) {
if (*l) { /* マークなどが残っている */
line_cat_body(l,wp0);
line_store_and_echo(wp0,l); /* こっそり前に付け足す */
}
line_delete1_echo_after_bag(CL); /* CL を削除する */
CL = wp0; /* 後ろに行く */
if ((CY = window_is_this_line_in_current(CL)) < 0) {
disp_cl_center();
}
} else { /* 0行になった */
disp_1line(CY,CL);
disp_check_1line_echo(CL);
}
line_cl_cl();
work_line_analyze();
CX0 = CPX = 0; /* 行頭へ */
}
}
/* 一行の2点間を削除し、フラグによりカットバッファに入れる */
/* 削除した中にマークがあったなら、削除の後ろにつめる:うう、最後が EOS きっと大丈夫 */
/* ユニットへのポインタと、バイト位置を与える */
/* b1 <= 削除 < b2 */
/* エコーしない */
void
work_delete_between(UNIT *p,int b1,int b2,int flag)
{
register int i;
UINT mask;
line_get_body(w,p); /* w に取り出す */
strncpy(l,w,i = b1); /* l に前を入れる */
strncpy(s,&w[b1],b2-b1); /* s に削除部分を入れる */
s[b2-b1] = EOS;
if (flag) {
mask = buff_add_to_cut_buff(s);
} else {
mask = mark_find_mark(s);
}
if (mask) { /* 削除した中にマークがあった */
register UINT m = 1,bc = 0;
for(;mask;m <<= 1,bc++) {
if (mask & m) {
mask ^= m; /* ビットを倒す */
l[i++] = XCODE_UP;
l[i++] = XCODE_MARK + bc;
}
}
}
l[i] = EOS;
strcat(l,&w[b2]); /* 後ろ部分を接続 */
line_store(p,l); /* エコーしない */
}
/* 現在のカーソル位置の1文字(1、2バイトコード)を削除する:エコーする */
/* バッファには入れない */
void
work_delete1char()
{
int b1,b2;
b1 = ANALYZE[CPX].BPOS;
b2 = ANALYZE[CPX+1].BPOS;
work_delete_cl_between(b1,b2,0);
}
/* CLの次の行の先頭の1文字を削除する */
/* エコーする */
void
work_delete1char_special()
{
register int i;
UBYTE w0[VERY_LONG_LINE];
STR p;
line_get_body(w0,CL->ATO);
p = line_skip_xcode(w0); /* 拡張コードをスキップする */
i = string_1or2_byte_code(*p);
strcpy(l,&p[i]);
work_xl_replace_minus(CL->ATO,CY+1);
}
/* 現在行を l に置き換える。画面全体にエコーする */
/* l は現在行(CL_DATA)よりも長くなくてはいけない */
/* bx はカーソルのあるべきバイト位置 */
/* 禁則処理の関係で、前の行へ送り込まれたら非零を返す */
int
work_cl_replace_plus(register int bx)
{
UBYTE wl[VERY_LONG_LINE];
int bb,ll,kflag;
UNIT *cl0;
cl0 = CL; /* トレースし直す時のために保存しておく */
if (kflag = work_cl_replace_minus()) {
bx += kflag;
if (bx < 0) { /* カーソルは前の行に移動する */
cl0 = CL = CL->MAE; /* cl0 が無くなっている可能性がある */
bx += CL->LENGTH;
bb = bx;
} else { /* カーソルは CL の上にある */
bb = 0;
if (!bx && (kflag < 0)) { /* 前の行に送られ、自分は行頭にいる */
if (CL == TAIL) {
UNIT *wp;
/* 前の行は一行で完結しており、CL はその先にある */
wp = line_get_free_and_store("");
line_append1_echo(wp);
CL = line_trace_byte(wp,0,bx,&bb,&ll);
}
} else {
CL = line_trace_byte(CL,0,bx,&bb,&ll);
}
}
} else { /* 禁則処理にともなう出し入れは無かった */
CL = line_trace_byte(CL,0,bx,&bb,&ll);
}
if ((CY = window_is_this_line_in_current(CL)) < 0) {
line_seigyou();
CL = line_trace_byte(cl0,0,bx,&bb,&ll); /* トレースし直す */
if (CMDMOD) { /* ED モードである */
if (ll > 0) { /* 後ろへ動いた */
disp_cl_y(CWY1);
} else {
disp_cl_y(CWY0);
}
} else { /* ME モードである */
disp_cl_center();
}
}
line_cl_cl();
work_line_analyze();
CPX = work_byte_to_CPX(bb);
CX0 = CX = ANALYZE[CPX].XPOS;
if (CPX && (line_cl_1byte(CPX-1) == CR)) { /* 左が改行 */
line_seigyou();
if (CL->ATO == TAIL) {
ctrl_b();
} else {
ctrl_f();
}
}
work_cursor_cpx();
}
/* 現在行を l に置き換える。画面全体にエコーする */
/* 禁則処理の関係で、前の行へ送り込まれたら非零を返す */
int
work_cl_replace_minus()
{
return(work_xl_replace_minus(CL,CY));
}
/* 指定された行を l に置き換える。画面全体にエコーする */
/* y は行座標 */
/* 禁則処理の関係で、前の行へ送り込まれたら非零を返す */
/* 前の行に何バイト送り込まれたかを返す */
int
work_xl_replace_minus(UNIT *xl,int y)
{
int flag,kflag = 0;
UBYTE w0[VERY_LONG_LINE],retw[VERY_LONG_LINE];
UNIT *cp,*np,*wp;
int ly,b0;
int POO =1; /* minus time flag */
ly = (CWY1-CWY0);
if (!*l) { /* 長さの無い行と置き換えるのだから、1行削除 */
line_seigyou();
wp = xl->ATO;
line_deleten_echo(xl->MAE,xl->ATO);
if (CL == xl) { /* xl が CL だった */
CL = wp;
}
kflag = string_2unit_check(wp->MAE,wp->ATO);
return(kflag);
}
if ((wp = xl->MAE) && (wp != HEAD)) { /* 前の実体がある */
switch(etc_sign(kflag = string_unit_line_check(wp,l))) {
UBYTE w[VERY_LONG_LINE * 2],w2[VERY_LONG_LINE * 2];
/* - = 前へ送った、0 = 送り無し、+ = 後ろへ送った */
/* 送ったバイト数を返す */
/* やり取りがある */
case 1: /* 後ろに送った */
line_get_body(w2,wp);
cut_2line_link_check(w2,l,w,l,CURRENT_JIZUME);
line_store_and_echo(wp,w);
break;
case -1: /* 前に送った */
/* CL が消えている可能性がある */
line_get_body(w2,wp);
cut_2line_link_check(w2,l,w,l,CURRENT_JIZUME);
line_store_and_echo(wp,w);
if (!*l) { /* 長さの無い行と置き換えるのだから、1行削除 */
line_seigyou();
wp = xl->ATO;
line_deleten_echo(xl->MAE,xl->ATO);
if (CL == xl) { /* wp が CL だった */
/* CL = HEAD->ATO;*/
CL = wp;
}
/* kflag = string_2unit_check(xl->MAE,xl->ATO);*/
return(kflag);
}
break;
case 0: /* やり取りが無い */
break; /* 何もしない */
}
}
cp = xl;
while((y < ly) || (POO)) {/* !!!!!! */
if ((np = cp->ATO) == TAIL){
/* 最後の行であるから l だけで複数行作って終わり */
cut_line(l,retw,l,CURRENT_JIZUME);
line_store_and_echo(cp,retw);
while(*l) {
cut_line(l,retw,l,CURRENT_JIZUME);
wp = line_get_free_and_store(retw);
line_append1_echo(wp);
}
return(kflag);
}
line_get_body(w0,np); /* w0 は常にその次の行の中身を示す */
/*sysflag = 1;*/
flag = cut_2line_link_check(l,w0,retw,l,CURRENT_JIZUME);
switch (etc_sign(flag)) {
case 0: /* 出入りが無かった */
line_store_and_echo(cp,retw);
return(kflag); /* 終わり */
case -1: /* 前に送られた */
if (etc_last(retw) == CR) { /* retw の終わりは改行 */
line_seigyou();
/* 一行削除:ただしその行は袋の後ろにあること */
line_delete1_echo_after_bag(np);
line_store_and_echo(cp,retw);
return(kflag); /* 終わり */
}
if (!*l) { /* 短過ぎたかも? */
strcpy(l,retw); /* 戻す */
np = np->ATO;
line_delete1_echo_after_bag(np->MAE);
if (np == TAIL) {
line_store_and_echo(cp,l);
break;
}
line_cat_body(l,np); /* その次の行を取って来る */
line_delete1_echo_after_bag(np);
break;
}
/* retw で1行作って良い */
line_store_and_echo(cp,retw);
cp = cp->ATO;
break;
case 1: /* 後ろに送った */
/* retw で1行作って良い */
line_store_and_echo(cp,retw);
cp = cp->ATO;
break;
default:
error("バグです3");
break;
}
y++;
/*
if (cp == SCREEN[CWY1]) {
etc_beep();etc_beep();etc_beep();POO = 0;
}
*/
}
/*
if (y != ly) {
error("バグです4");
}
*/
np = cp->ATO;
line_empty_bag(w0); /* 最下行なら袋から持ってくる */
flag = cut_2line_link_check(l,w0,retw,l,CURRENT_JIZUME);
switch (etc_sign(flag)) {
case 0: /* 出入りが無かった */
case 1: /* 後ろに送った */
line_store_and_echo(cp,retw);
line_to_bag(l); /* 袋に戻す */
break;
case -1: /* 前に送った */
if (!*l && (etc_jlast(retw) != CR)) {
/* 短過ぎた可能性がある、もしくはちょうどぴったり */
if (np == TAIL) { /* 次の行はない */
line_store_and_echo(cp,retw);
line_to_bag(l); /* 袋に戻す */
break;
}
strcpy(l,retw); /* 戻す */
line_get_body(w0,np);
/* その次の行=画面外の最初の行の中身を取って来る */
line_delete1_echo_after_bag(np); /* すぐ外の行を削除 */
cut_2line_link_check(l,w0,retw,l,CURRENT_JIZUME);
line_store_and_echo(cp,retw);
line_to_bag(l); /* 残りを袋に入れる */
break;
} else {
line_store_and_echo(cp,retw);
line_to_bag(l); /* 残りを袋に入れる */
break;
}
default:
error("バグです5");
break;
}
return(kflag);
}
/* CPX の位置にカーソルを表示する */
void
work_cursor_cpx()
{
if (TBUFFC || TBUFFC_R) {
window_loc(TX,TY);
} else {
window_loc(CX = ANALYZE[CPX].XPOS,CY);
}
}
/* CPX の位置にカーソルを表示する */
void
work_cursor_cpx0()
{
window_loc(CX = ANALYZE[CPX].XPOS,CY);
}
/* CX0 に最も近い CPX を返す */
int
work_CX0_to_CPX(int cx00)
{
register int i = 0;
register int x;
if (!cx00) { /* 0なら0 */
return(0);
}
while(1) {
x = ANALYZE[i].XPOS;
if (x > cx00) return(i-1); /* 行き過ぎた */
if (x == cx00) { /* 一致した */
if (line_cl_1byte(i-1) == CR) { /* 左が改行 */
i--;
}
return(i);
}
if (i && (x == 0)) { /* 行が短い */
if (line_cl_1byte(--i-1) == CR) { /* 左が改行 */
i--;
}
return(i);
}
i++;
}
}
/* CL の b バイト目に当る CPX を返す */
int
work_byte_to_CPX(int b)
{
register int i = 0;
register int bp;
while(1) {
bp = ANALYZE[i].BPOS;
if (bp > b) return(i-1); /* 行き過ぎた */
if (bp == b) return(i); /* 一致した */
i++;
}
}
int get_buff_c;
UBYTE beta0[VERY_LONG_LINE * 2],gamma0[VERY_LONG_LINE * 2];
/* αとのやり取りを考慮しつつ、β+カットバッファ+γを、整行したカットバッファリストにする */
/* -1 = 空、さもなくば、CUT_BUFF の総バイト長を返す */
/* αが NULL ならやり取りのチェックはしない */
/* αとのやり取りがたったなら、αそのものの長さを代えて戻す */
int
work_make_cut_buff0_list(STR alpha,STR beta,STR gamma)
{
int c = 0,c0 = 0,tbl;
under_print((STR)"カットバッファリスト作成中…");
line_deleten_list(CUT_BUFF_HEAD0,CUT_BUFF_TAIL0);
CUT_BUFF_HEAD0 = CUT_BUFF_TAIL0 = NIL;
get_buff_c = -1;
strcpy(beta0,beta);
strcpy(gamma0,gamma);
*l = EOS;
tbl = -(strlen(beta) + strlen(gamma)); /* 最初の長さ */
c = work_get_buff(l); /* 最初の1行を取って来る */
tbl += c;
if (c && alpha) { /* 何か持ってきた */
/* 十分に長い1行を取ってきたのだから、alpha とのやり取りは判定可能 */
/* いきなり切る */
cut_2line_link_check(alpha,l,alpha,l,CURRENT_JIZUME);
}
while(1) {
cut_line(l,s,l,CURRENT_JIZUME);
if ((strlen(l) > 0) || (etc_last(s) == CR)) { /* s にはしっかり1行ある */
work_append_cut_buff0_list(s);
continue; /* 続行 */
} else { /* s にしっかり1行ある保証がない */
strcpy(l,s); /* 戻す */
c = work_get_buff(l); /* 取って来る(追加) */
tbl += c;
if (!c) { /* もう無い */
if (*l) { /* 1行にはならないが何かある */
work_append_cut_buff0_list(l);
}
under_blanc();
return(tbl);
} else { /* 取ってこれた */
continue;
}
}
}
}
UNIT *
work_append_cut_buff0_list(UBYTE *s)
{
UNIT *p;
if (!(p = line_get_free_and_store(s))) return(NIL);
if (CUT_BUFF_HEAD0) { /* 整行されたカットバッファリストがある */
CUT_BUFF_TAIL0->ATO = p; /* 最後の次が手持ちになる */
p->MAE = CUT_BUFF_TAIL0; /* 手持ちの前は最後 */
p->ATO = NIL; /* 新しい最後は NIL を指す */
CUT_BUFF_TAIL0 = p; /* 新しい最後を指す */
} else { /* フリーラインがない */
CUT_BUFF_HEAD0 = CUT_BUFF_TAIL0 = p;
p->MAE = p->ATO = NIL;
}
return(p);
}
/* beta0 + カットバッファリスト + gamma0 から文字列を返して行く(追加) */
/* 長さを返す */
/* 長さが0ならもう無いということ */
/* カウンタを初期化してから使う必要あり */
int
work_get_buff(STR d)
{
int len,c;
UBYTE w[VERY_LONG_LINE];
if (get_buff_c == -1) {
get_buff_c = 0;
strcat(d,beta0);
len = strlen(beta0);
} else {
len = 0;
}
while(string_disp_len(d) < CURRENT_JIZUME+6) {
c = buff_get_from_cut_buff(w,0,get_buff_c);
/* カットバッファより1行取ってくる */
if (c < 0) { /* もうない */
strcat(d,gamma0);
len += strlen(gamma0);
*gamma0 = EOS;
return(len);
}
get_buff_c = c + 1;
strcat(d,w);
len += strlen(w);
}
return(len);
}
/* 整行されたカットバッファリストの頭から順番に1つづつ外して行く */
UNIT *
work_get_from_cut_buff0_list()
{
UNIT *wp;
if (wp = CUT_BUFF_HEAD0) {
CUT_BUFF_HEAD0 = CUT_BUFF_HEAD0->ATO;
} /* HEAD が NIL なら TAIL は無効だからこれでいいのだ */
return(wp);
}
/* CL が指している行(CL_DATA)の解析 */
void
work_line_analyze()
{
register int i = 1;
int bc = 0;
int xc;
xc = 0;
ANALYZE[0].BPOS = ANALYZE[0].XPOS = 0;
if (CL) {
do {
bc = line_touch_next_char(bc,&xc);
ANALYZE[i].BPOS = bc;
ANALYZE[i++].XPOS = xc;
} while(CL_DATA[bc]);
ANALYZE[i].BPOS = bc+1;
ANALYZE[i].XPOS = 0; /* 最後を納めて終わり */
} else {
error("バグです。奇妙な行を処理しました");
}
}
/* 2つの指定行の指定バイト位置の間を、s で置き換える */
/* len < 0 なら、文字列の長さでトレースする */
/* さもなくば len でトレースする */
/* 画面にエコーする */
void
work_replace_str_echo(UNIT *p1,int bp1,UNIT *p2,int bp2,STR s,int len,int yy)
{
int ccc;
UBYTE w[VERY_LONG_LINE*4];
int bb,ll;
register UNIT *wp,*wp0;
if (len < 0) {
len = strlen(s);
}
line_get_body(l,p1);
strcpy(&l[bp1],s);
line_get_body(w,p2);
strcat(&l[bp1],&w[bp2]);
if (((wp = p1) != p2) && (p2 != TAIL)){
line_deleten_echo(p1,p2->ATO);
}
work_xl_replace_minus_xxx(p1,yy);
if ((p1->MAE != HEAD) && ((ccc = string_2unit_check(p1->MAE,p1)) < 0)) {/* 前へ送った:rare case! */
line_get_body(l,p1);
line_cat_body(l,p1->ATO);
line_store(p1->ATO,"");
work_xl_replace_minus(p1,bp1+len);
if ((len+ccc) < 0) { /* カーソルは前の行に移動する */
CL = CL->MAE;
bb = (len += CL->LENGTH);
#if 0
etc_beep();
if (--CY < 0) { /* 上にはみ出た */
etc_beep();etc_beep();
}
#endif
} else { /* カーソルは p1(+len) の上にある */
/* カーソルのある行は(前へは)移動しない */
len += ccc;
if (!len) { /* 前の行に送られ、自分は行頭にいる */
if (CL == TAIL) {
UNIT *wp;
/* 前の行は一行で完結しており、CL はその先にある */
wp = line_get_free_and_store("");
line_append1_echo(wp);
disp_1line_rel(window_is_this_line_in_current(wp),wp);
CL = line_trace_byte(wp,0,len,&bb,&ll);
} else {
bb = 0;
}
} else {
CL = line_trace_byte(p1,bp1,len,&bb,&ll);
CY = yy + ll; /* CY は画面上 */
}
}
} else { /* 禁則処理にともなう出し入れは無かった */
CL = line_trace_byte(p1,bp1,len,&bb,&ll);
CY = yy + ll; /* CY は画面上 */
}
/*=================================*/
line_cl_cl();
work_line_analyze();
CPX = work_byte_to_CPX(bb);
CX0 = CX = ANALYZE[CPX].XPOS;
if (CPX && (line_cl_1byte(CPX-1) == CR)) { /* 左が改行 */
if (CL->ATO == TAIL) {
ctrl_b();
} else {
ctrl_f();
}
}
}
/* 2つの指定行の指定バイト位置の間を、s で置き換える */
/* 画面にエコーする */
/* トレースしない */
/* CL とは関係なく実行出来る */
int
work_replace_str_echo_xxx(UNIT *p1,int bp1,UNIT *p2,int bp2,STR s)
{
UBYTE w[VERY_LONG_LINE*4];
int bb,ll;
register UNIT *wp,*wp0;
int flag;
jump(p1,bp1); /* CL = p1,line_cl_cl() を実行する */
line_get_body(l,p1); /* 行を読み出す */
strcpy(&l[bp1],s); /* 置き換え部分を持ってくる */
line_get_body(w,p2); /* 行を読み出す */
strcat(&l[bp1],&w[bp2]);
if (((wp = p1) != p2) && (p2 != TAIL)){
line_deleten_echo(p1,p2->ATO);
flag = 1;
} else {
flag = 0;
}
work_xl_replace_minus_xxx(p1,CY);
return(flag);
}
/* 現在のカーソル位置に1バイトコードを挿入する:エコーする */
void
work_insert1(UBYTE c)
{
register int i;
if ((FP_MODE[3] == 'H') && /* 変換モード */
(!(!TBUFFC && ((c == 13)||(c == 10)||(c == TAB)||(c == ' '))))) {/* (もしくは、最初に改行、タブ)でない */
int nx,ny;
if (TBUFFC) { /* 未確定入力追加 */
xf_append_tb(c);
} else { /* 未確定入力開始 */
TTOPL00 = line_my_top();
TL00 = TL1 = TL0 = CL; /* 変換バッファの開始行 */
CRX = CRY = 0;
TPX00 = TPX0 = CPX;
TX00 = TX = TX0 = CX;
TY00 = TY = TY0 = CY;
TBP1 = TBP00 = TBP0 = ANALYZE[CPX].BPOS;
xf_append_tb(c);
}
} else {
/*
if (sysflag) {
window0();
printf("\n(%d)(%d)[%s]\n",CPX,ANALYZE[CPX].BPOS,CL_DATA);
binkey();
}
*/
line_cl_strncpy(l,i = ANALYZE[CPX].BPOS); /* ok */
l[i] = c;
l[i+1] = EOS;
line_cl_strcat(l,i); /* ok */
work_cl_replace_plus(i+1);
/*
window0();
printf("\n(%d)(%d)[%s]\n",CPX,ANALYZE[CPX].BPOS,CL_DATA);
binkey();
sysflag = 1;
*/
}
}
/* 現在のカーソル位置に2バイトコードを挿入する:エコーする */
void
work_insert2(UINT c)
{
register int i;
if ((FP_MODE[3] == 'H') && /* 変換モード */
(!(!TBUFFC && (c == 0x8140)))) {/* (もしくは、最初に空白)でない */
int nx,ny;
if (TBUFFC) { /* 未確定入力追加 */
xf_append_tb(c);
} else { /* 未確定入力開始 */
TTOPL00 = line_my_top();
TL00 = TL1 = TL0 = CL; /* 変換バッファの開始行 */
CRX = CRY = 0;
TPX00 = TPX0 = CPX;
TX00 = TX = TX0 = CX;
TY00 = TY = TY0 = CY;
TBP1 = TBP00 = TBP0 = ANALYZE[CPX].BPOS;
xf_append_tb(c);
}
xf_init_tb_r0();
} else {
UINT cd;
if ((c == L'゜') && (cd = etc_handakuten_able()) || ((c == L'゛') && (cd = etc_dakuten_able()))) {
/* YES なら既に ctrl_b してある */
ctrl_d();
c = cd;
}
line_cl_strncpy(l,i = ANALYZE[CPX].BPOS); /* ok */
l[i] = (UBYTE) (c >> 8);
l[i+1] = (UBYTE) (c & 0xff);
l[i+2] = EOS;
line_cl_strcat(l,i); /* ok */
work_cl_replace_plus(i+2);
if (TBUFFC_R) { /* 未確定ローマ字を表示 */
xf_init_tb00();
TTOPL00 = line_my_top();
TL00 = TL1 = TL0 = CL; /* 変換バッファの開始行 */
CRX = CRY = 0;
TPX00 = TPX0 = CPX;
TX00 = TX = TX0 = CX;
TY00 = TY = TY0 = CY;
TBP1 = TBP00 = TBP0 = ANALYZE[CPX].BPOS;
xf_disp_insert(&TX,&TY);
}
}
}
/* 指定された行を l に置き換える。画面全体にエコーする */
/* y は行座標 */
/* 禁則処理の関係で、前の行へ送り込まれたら非零を返す */
/* 前の行に何バイト送り込まれたかを返す */
int
work_xl_replace_minus_xxx(UNIT *xl,int y)
{
int flag,kflag = 0;
UBYTE w0[VERY_LONG_LINE],retw[VERY_LONG_LINE];
UNIT *cp,*np,*wp;
int ly,b0;
ly = (CWY1-CWY0);
cp = xl;
while(y < ly) {
if ((np = cp->ATO) == TAIL) {
/* 最後の行であるから l だけで複数行作って終わり */
cut_line(l,retw,l,CURRENT_JIZUME);
line_store_and_echo(cp,retw);
/* line_delete1_echo_after_bag(cp);*/
/* wp = line_get_free_and_store(retw);*/
/* line_append1_echo(wp);*/
y++;
while(*l) {
cut_line(l,retw,l,CURRENT_JIZUME);
wp = line_get_free_and_store(retw);
line_append1_echo(wp);
y++;
}
if (y < ly) {
disp_middle_flush(y,TAIL);
}
return(kflag);
}
line_get_body(w0,np); /* w0 は常にその次の行の中身を示す */
flag = cut_2line_link_check(l,w0,retw,l,CURRENT_JIZUME);
switch (etc_sign(flag)) {
case 0: /* 出入りが無かった */
line_store_and_echo(cp,retw);
if (++y < ly) {
disp_middle_flush(y,cp->ATO);
}
return(kflag); /* 終わり */
case -1: /* 前に送られた */
if (etc_last(retw) == CR) { /* retw の終わりは改行 */
line_seigyou();
/* 一行削除:ただしその行は袋の後ろにあること */
line_delete1_echo_after_bag(np);
line_store_and_echo(cp,retw);
if (++y < ly) {
disp_middle_flush(y,cp->ATO);
}
return(kflag); /* 終わり */
}
if (!*l) { /* 短過ぎた */
strcpy(l,retw); /* 戻す */
np = np->ATO;
line_delete1_echo_after_bag(np->MAE);
if (np == TAIL) {
/* wp = line_get_free_and_store(l);*/
/*error("-12");*/
line_store_and_echo(cp,l);
/* line_delete1_echo_after_bag(TAIL->MAE);*/
break;
}
line_cat_body(l,np); /* その次の行を取って来る */
line_delete1_echo_after_bag(np);
/* cp = cp->ATO;*/ /* loop top で np 更新 */
break;
}
/* retw で1行作って良い */
line_store_and_echo(cp,retw);
cp = cp->ATO;
break;
case 1: /* 後ろに送った */
/* retw で1行作って良い */
/* line_store(cp,retw);*/
line_store_and_echo(cp,retw);
/*window0();printf("(%s)[%x][%x]",retw,cp,cp->ATO);binkey();*/
cp = cp->ATO;
break;
default:
error("バグです6");
break;
}
y++;
}
if (y != ly) {
error("バグです7");
}
np = cp->ATO;
line_empty_bag(w0); /* 最下行なら袋から持ってくる */
flag = cut_2line_link_check(l,w0,retw,l,CURRENT_JIZUME);
switch (etc_sign(flag)) {
case 0: /* 出入りが無かった */
case 1: /* 後ろに送った */
line_store_and_echo(cp,retw);
line_to_bag(l); /* 袋に戻す */
break;
case -1: /* 前に送った */
if (!*l) { /* 短過ぎた */
if (np == TAIL) { /* 次の行はない */
line_store_and_echo(cp,retw);
line_to_bag(l); /* 袋に戻す */
break;
}
strcpy(l,retw); /* 戻す */
line_get_body(w0,np); /* その次の行を取って来る */
line_delete1_echo_after_bag(np); /* すぐ外の行を削除 */
cut_2line_link_check(l,w0,retw,l,CURRENT_JIZUME);
line_store_and_echo(cp,retw);
line_to_bag(l); /* 残りを袋に入れる */
break;
} else {
line_store_and_echo(cp,retw);
line_to_bag(l); /* 残りを袋に入れる */
break;
}
default:
error("バグです8");
break;
}
return(kflag);
}
/* 2点間を削除してカットバッファに入れる */
/* 削除した中にマークがあったなら、マークを移動、取り除いてカットバッファに入れる */
/* 2つユニットへのポインタと、バイト位置を与える */
void
work_delete_to_cut_buff_xxx(UNIT *p1,int b1,UNIT *p2,int b2)
{
work_delete_to_cut_buff0(p1,b1,p2,b2,0);
}
/* 2点間を削除してカットバッファに入れる */
/* 削除した中にマークがあったなら、マークを移動、取り除いてカットバッファに入れる */
/* 2つユニットへのポインタと、バイト位置を与える */
void
work_delete_to_cut_buff(UNIT *p1,int b1,UNIT *p2,int b2)
{
work_delete_to_cut_buff0(p1,b1,p2,b2,1);
}
/* 2点間を削除してカットバッファに入れる */
/* 削除した中にマークがあったなら、マークを移動、取り除いてカットバッファに入れる */
/* 2つユニットへのポインタと、バイト位置を与える */
void
work_delete_to_cut_buff0(UNIT *p1,int b1,UNIT *p2,int b2,int flag)
{
UBYTE wl[VERY_LONG_LINE*4];
if (etc_line_order(&p1,&b1,&p2,&b2)) { /* 勝手に入れ替えてくれる */
if (p1 == p2) { /* 同じ行であった */
work_delete_between(p1,b1,b2,flag); /* その行の一部を削除 */
line_get_body(l,p1); /* 行の内容を取り出す */
CL = p1; /* 現在行はその行 */
if (CL->ATO != TAIL) {
line_cat_body(l,CL->ATO);
line_delete1_echo_after_bag(CL->ATO);
}
work_cl_replace_plus(b1);
} else {
UNIT *wp,*wp0;
int w;
work_delete_between(p1,b1,line_length(p1),flag);
line_get_body(wl,p1);
wp = p1->ATO;
while(wp != p2) {
work_delete_between(wp,0,line_length(wp),flag);
line_cat_body(wl,wp);
wp = wp->ATO;
}
/* wl の中には残りの文字列とマークの両方が入っている */
work_delete_between(p2,0,b2,flag);
strcpy(l,wl);
line_cat_body(l,p2);
line_deleten_echo(p1,p2->ATO);
CL = p1;
CY = window_is_this_line_in_current(CL);
/*
window0();
printf("[%s]",l);binkey();
*/
work_cl_replace_plus(b1);
disp_cl_y(CY);
}
} else {
error("バグです9");
}
}
/* 2点間をカットバッファに入れる */
/* 削除した中にマークがあったなら、当然取り除いてカットバッファに入れる */
/* 2つユニットへのポインタと、バイト位置を与える */
void
work_copy_to_cut_buff(UNIT *p1,int b1,UNIT *p2,int b2)
{
if (etc_line_order(&p1,&b1,&p2,&b2)) { /* 勝手に入れ替えてくれる */
if (p1 == p2) { /* 同じ行であった */
work_copy_to_cut_buff_1line(p1,b1,b2);
} else {
UNIT *wp;
work_copy_to_cut_buff_1line(p1,b1,line_length(p1));
wp = p1->ATO;
while(wp != p2) {
work_copy_to_cut_buff_1line(wp,0,line_length(wp));
wp = wp->ATO;
}
work_copy_to_cut_buff_1line(p2,0,b2);
}
} else {
error("バグです10");
}
}
/* 一行の2点間をカットバッファに入れる */
/* 削除した中にマークがあったなら、当然取り除いてカットバッファに入れる */
/* ユニットへのポインタと、バイト位置を与える */
void
work_copy_to_cut_buff_1line(UNIT *p,int b1,int b2)
{
register int i;
line_get_body(w,p);
strncpy(s,&w[b1],b2-b1);
s[b2-b1] = EOS;
buff_add_to_cut_buff(s);
}
/* 現在のカーソル位置に1バイトコードを挿入する:カーソルは進めない */
/* エコーする */
void
work_insert1_right(UBYTE c)
{
register int i;
line_cl_strncpy(l,i = ANALYZE[CPX].BPOS); /* ok */
l[i] = c;
l[i+1] = EOS;
line_cl_strcat(l,i); /* ok */
work_cl_replace_minus();
}
void
work_set_underline(UNIT *p1,int b1,UNIT *p2,int b2)
{
register UNIT *wp;
register int be;
if (etc_line_order(&p1,&b1,&p2,&b2)) { /* 勝手に入れ替えてくれる */
while(1) {
if (p1 == p2) { /* 同じ行であった */
/* b1,b2 の間にアンダーラインコードを埋め込んで終了 */
work_set_underline1(p1,b1,b2);
if (b1 != b2) {
change_check();
}
ctrl_l();
break;
} else { /* (p1,b1)-(p1,last) にコードを埋め込む */
work_set_underline1(p1,b1,be = line_length(p1));
if (b1 != be) {
change_check();
}
}
p1 = p1->ATO;
b1 = 0;
}
} else {
error("バグです11");
}
}
/* p1 の b1 から b2 までにアンダーラインを挿入する */
void
work_set_underline1(UNIT *p1,int b1,int b2)
{
UBYTE l[VERY_LONG_LINE],s[VERY_LONG_LINE];
register int count,bc,bc0;
int dummy;
register UBYTE *p;
line_get_body(l,p1);
count = bc = b1;
strncpy(s,l,count);
while(bc < b2) {
/* p[bc] から始めて、次の文字までのバイト数を返す */
/* *xc から表示しているとして、*xc を更新する */
bc = line_touch_next_char_x(l,bc0 = bc,&dummy); /* 次の実体までのカウント */
/* ^実体を越える */
p = string_search_xcode(&l[bc0]); /* 最初の XCODE の位置 */
while(1) {
/*
window0();
printf("{p=%x}{bc=%x}{bc0=%x}\n",p,bc,bc0);
printf("[bc]=%x}{[bc0]=%x}\n",l[bc],l[bc0]);binkey();
*/
if (*line_skip_xcode(&l[bc0]) == CR) {
/* 改行にアンダーラインはつかない */
break;
}
if ((!p) || ((UINT)p >= (UINT)&l[bc])) {
/* 無い or もっと先 */
s[count++] = XCODE_UP;
s[count++] = XCODE_UL;
break;
} else {
if (*(++p) == XCODE_UL) { /* 既にアンダーラインがあった */
break; /* 何もしないで抜ける */
}
p = string_search_xcode(p); /* 次の XCODE の位置 */
}
}
strncpy(&s[count],&l[bc0],bc-bc0);
count += bc-bc0;
}
if (l[bc]) {
int ll;
ll = strlen(&l[bc]);
strncpy(&s[count],&l[bc],ll);
s[count+ll] = EOS;
} else {
s[count] = EOS;
}
line_store(p1,s);
}
void
work_erase_underline(UNIT *p1,int b1,UNIT *p2,int b2)
{
register UNIT *wp;
register int be;
if (etc_line_order(&p1,&b1,&p2,&b2)) { /* 勝手に入れ替えてくれる */
while(1) {
if (p1 == p2) { /* 同じ行であった */
/* b1,b2 の間にアンダーラインコードを消去して終了 */
work_erase_underline1(p1,b1,b2);
if (b1 != b2) {
change_check();
}
ctrl_l();
break;
} else { /* (p1,b1)-(p1,last) のコードを消去 */
work_erase_underline1(p1,b1,be = line_length(p1));
if (b1 != be) {
change_check();
}
}
p1 = p1->ATO;
b1 = 0;
}
} else {
error("バグです12");
}
}
/* p1 の b1 から b2 までのアンダーラインを消去する */
void
work_erase_underline1(UNIT *p1,int b1,int b2)
{
UBYTE l[VERY_LONG_LINE],s[VERY_LONG_LINE];
register int count,bc;
line_get_body(l,p1);
count = bc = b1;
strncpy(s,l,count);
while(bc < b2) {
if ((l[bc] == XCODE_UP) && (l[bc+1] == XCODE_UL)) {
bc += 2;
continue;
}
s[count++] = l[bc++];
}
if (l[bc]) {
int ll;
ll = strlen(&l[bc]);
strncpy(&s[count],&l[bc],ll);
s[count+ll] = EOS;
} else {
s[count] = EOS;
}
line_store(p1,s);
}